package smartlifev30.com.sdk.net.baiwei;

import android.util.Log;

import java.nio.charset.Charset;

import io.netty.channel.ChannelHandlerContext;
import smartlifev30.com.sdk.api.CallBack;
import smartlifev30.com.sdk.api.service_app.HeartbeatImpl;
import smartlifev30.com.sdk.bean.response.HeartbeatResponse;
import smartlifev30.com.sdk.net.baiwei.protocol.Header;
import smartlifev30.com.sdk.net.core.BaseNettyClient;
import smartlifev30.com.sdk.net.core.ConnectStatus;

/**
 * baiwei Client
 *
 * @author tys
 * @date 2018/8/11
 */

public class Client extends BaseNettyClient<String, String> {

    private HeartbeatImpl heartbeat;

    private Client(Builder builder) {
        setConnectTimeOut(builder.connectTimeOut);
        setReadTimeOut(builder.readTimeOut);
        setWriteTimeOut(builder.writeTimeOut);
        setAllTimeOut(builder.allTimeOut);
        setUserEventTriggeredListen(builder.userEventTriggeredListen);
        setStatusChangeListen(builder.statusChangeListen);
    }

    /**
     * 解码
     *
     * @param bytes
     * @return 返回消息內容 不包括协议头, 协议解析,检查失败返回"".
     */
    @Override
    protected String decoder(byte[] bytes) {
        if (Header.check(bytes)) {
            return new String(bytes, Header.HEAD_LENGTH,
                    bytes.length - Header.HEAD_LENGTH, Charset.forName("UTF-8"));
        }
        return "";
    }

    @Override
    protected byte[] encoder(String content) {
        String message = Header.add(content);
        return message.getBytes();
    }

    @Override
    public void receive(String s) {
        Log.e("0-0-", "receive:" + s);
        ResponseHelper.sendMessage(s);
    }

    @Override
    protected void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
        super.userEventTriggered(ctx, evt);
        //发送心跳包
        if (heartbeat == null) {
            heartbeat = new HeartbeatImpl();
        }
        heartbeat.hearBeat2Server(NetManager.userName, NetManager.token, new CallBack<HeartbeatResponse>() {
            @Override
            protected void onSuccess(HeartbeatResponse response) {
                Log.e("0-0-", "收到心跳:"+response.toString());
            }
        });
    }

    @Override
    protected void connectStatusChange(ConnectStatus connectStatus) {
        super.connectStatusChange(connectStatus);
        //断开 ===> 有网重连, (不一定能连上, 和服务器的网不一定通)
        //连上了  ===>
//        connect();
    }


    public static class Builder {

        /**
         * 连接超时时间(s)
         */
        private int connectTimeOut = 30;

        /**
         * 读事件间隙,指定时间内未发生读事件将触发{@link UserEventTriggeredListen#readerIdle(ChannelHandlerContext)}
         * 0表示未设置,用于心跳设置.
         */
        private int readTimeOut = 0;

        /**
         * 写事件间隙,指定时间内未发生写事件将触发{@link UserEventTriggeredListen#writerIdle(ChannelHandlerContext)}
         * 0表示未设置,用于心跳设置
         */
        private int writeTimeOut = 60;

        /**
         * 读,写事件间隙,指定时间内未发生读写事件将触发{@link UserEventTriggeredListen#allIdle(ChannelHandlerContext)}
         * 0表示未设置,用于心跳设置
         */
        private int allTimeOut = 0;


        /**
         * 用户事件, 用于心跳设置(不要忘了设置对应事件的时间比如：{@link #writeTimeOut})
         */
        private UserEventTriggeredListen userEventTriggeredListen;

        /**
         * 网络状态改变回到。依赖于Netty的{@link NettyClientHandler#channelActive(ChannelHandlerContext)}和{@link NettyClientHandler#channelInactive(ChannelHandlerContext)}
         */
        private ConnectStatusChangeListen statusChangeListen;

        public Builder connectTimeOut(int connectTimeOut) {
            this.connectTimeOut = connectTimeOut;
            return this;
        }

        public Builder readTimeOut(int readTimeOut) {
            this.readTimeOut = readTimeOut;
            return this;
        }

        public Builder writeTimeOut(int writeTimeOut) {
            this.writeTimeOut = writeTimeOut;
            return this;
        }

        public Builder allTimeOut(int allTimeOut) {
            this.allTimeOut = allTimeOut;
            return this;
        }


        public Builder userEventTriggeredListen(UserEventTriggeredListen userEventTriggeredListen) {
            this.userEventTriggeredListen = userEventTriggeredListen;
            return this;
        }

        public Builder statusChangeListen(ConnectStatusChangeListen statusChangeListen) {
            this.statusChangeListen = statusChangeListen;
            return this;
        }

        public Client build() {
            return new Client(this);
        }
    }

    public static class SimpleUserEventTriggeredListen implements UserEventTriggeredListen {

        @Override
        public void readerIdle(ChannelHandlerContext ctx) {

        }

        @Override
        public void writerIdle(ChannelHandlerContext ctx) {

        }

        @Override
        public void allIdle(ChannelHandlerContext ctx) {

        }
    }
}
